﻿using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.Core.WechatPayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;
using AiQiuQuan.Sport.WebApi.Entities;
using DotNetCore.CAP;
using AiQiuQuan.Sport.Model.Models;

namespace AiQiuQuan.Sport.WebApi.HangfireServices
{
    /// <summary>
    /// 转账状态更新定时服务
    /// </summary>
    [ReccuringJobCron("0 0/10 * * * ?")]
    public class TransferAccountHangfireService : IHangfireService
    {
        private readonly ILogger<TransferAccountHangfireService> _logger;
        private readonly IWechatPayV3HttpClientFactory _wechatPayV3HttpClientFactory;
        private readonly ITransferAccountRepository _transferAccountRepository;
        private readonly ICapPublisher _capPublisher;
        private readonly IVenueWithdrawRepository _venueWithdrawRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public TransferAccountHangfireService(
            IWechatPayV3HttpClientFactory wechatPayV3HttpClientFactory,
            ITransferAccountRepository transferAccountRepository,
            ILogger<TransferAccountHangfireService> logger,
            ICapPublisher capPublisher,
            IVenueWithdrawRepository venueWithdrawRepository)
        {
            _logger = logger;
            _wechatPayV3HttpClientFactory = wechatPayV3HttpClientFactory;
            _transferAccountRepository = transferAccountRepository;
            _capPublisher = capPublisher;
            _venueWithdrawRepository = venueWithdrawRepository;
        }

        /// <summary>
        /// 执行
        /// </summary>
        public async Task ExecuteAsync()
        {
            var transferOrderList = await _transferAccountRepository.AsNoTracking().Where(m => m.State == TransferStateEnum.Processing)
                .OrderBy(m => m.CreateTime).Take(100).ToListAsync();
            var successList = new List<Guid>();
            var faildList = new List<Guid>();
            var venueWithdrawFaildList = new List<TransferAccountOrder>();//场馆提现失败账单
            if (transferOrderList.Any())
            {
                var request = new GetTransferBatchByBatchIdRequest
                {
                    RequireQueryDetail = false,
                };
                foreach (var item in transferOrderList)
                {
                    if (!string.IsNullOrWhiteSpace(item.ThirdTransferId))
                    {
                        request.BatchId = item.ThirdTransferId;
                        var wxpayClient = _wechatPayV3HttpClientFactory.Create();
                        var rep = await wxpayClient.ExecuteGetTransferBatchByBatchIdAsync(request);
                        if (rep.IsSuccessful())
                        {
                            if (rep.TransferBatch.BatchStatus == "FINISHED")
                            {
                                successList.Add(item.ID);
                            }
                            else if (rep.TransferBatch.BatchStatus == "CLOSED")
                            {
                                _logger.LogInformation($"微信转账失败：{item.ID},{rep.TransferBatch.BatchStatus},{rep.TransferBatch.CloseReason}");
                                faildList.Add(item.ID);
                                if (item.BusinessType == BusinessTypeEnum.VenueSite)
                                {
                                    venueWithdrawFaildList.Add(item);
                                }
                            }
                        }

                        await Task.Delay(100);
                    }
                }

                //update
                if (successList.Any())
                {
                    var successBuilder = await _transferAccountRepository.UpdatePartialAsync();
                    successBuilder = successBuilder.Set(m => m.State, TransferStateEnum.Success).Where(m => successList.Contains(m.ID));
                    await successBuilder.ExecuteAsync();
                }

                if (faildList.Any())
                {
                    var faildBuilder = await _transferAccountRepository.UpdatePartialAsync();
                    faildBuilder = faildBuilder.Set(m => m.State, TransferStateEnum.Faild).Where(m => faildList.Contains(m.ID));
                    await faildBuilder.ExecuteAsync();
                }

                //场馆提现转账失败，退回对应场馆金额
                if (venueWithdrawFaildList.Any())
                {
                    var accountDetailList = new List<VenueInfoAccountDetailAddDto>();
                    foreach (var item in venueWithdrawFaildList)
                    {
                        var withdraw = await _venueWithdrawRepository.FirstOrDefaultAsync(m => m.ID == item.BusinessId);
                        var amount = withdraw.VW_Total.GetValueOrDefault() + withdraw.VW_ServicePrice.GetValueOrDefault();
                        var venueAccountDetail = new VenueInfoAccountDetailAddDto
                        {
                            VenueID = withdraw.VenueInfoID.Value,
                            Amount = amount,
                            OperateType = VenueAccountOperateEnum.Add,
                            SourceType = VenueAccountSourceEnum.WithdrawTransferFaild,
                            Remark = $"提现单:{withdraw.VW_Code}转账失败，退回金额:{amount}"
                        };
                        accountDetailList.Add(venueAccountDetail);
                    }

                    await _capPublisher.PublishAsync(MessageTopic.VENUE_ACCOUNT_DETAIL_ADD, accountDetailList);
                }
            }
        }
    }
}
